<template>
  <!--
  AI生成测试用例页面
  作者: heruopu
  © 2025 Heruopu. All rights reserved.
  -->
  <div class="ai-generation">
    <div class="container">
      <!-- 页面标题区域 -->
      <div class="page-header">
        <h2 class="page-title">AI 需求分析助手</h2>
        <p class="page-description">输入或上传需求文档，我们将为您生成详细的需求分析报告</p>
      </div>

      <!-- 现代化流程指示器 - 动态显示高亮和完成状态 -->
      <div class="step-indicator">
        <div class="step" :class="{ active: currentStep >= 1, completed: currentStep > 1 }">
          <div class="step-number">1</div>
          <div class="step-text">基础配置</div>
        </div>
        <div class="arrow" :class="{ active: currentStep > 1 }">→</div>
        <div class="step" :class="{ active: currentStep >= 2, completed: currentStep > 2 }">
          <div class="step-number">2</div>
          <div class="step-text">需求分析</div>
        </div>
        <div class="arrow" :class="{ active: currentStep > 2 }">→</div>
        <div class="step" :class="{ active: currentStep >= 3, completed: currentStep > 3 }">
          <div class="step-number">3</div>
          <div class="step-text">思维导图</div>
        </div>
        <div class="arrow" :class="{ active: currentStep > 3 }">→</div>
        <div class="step" :class="{ active: currentStep >= 4, completed: currentStep > 4 }">
          <div class="step-number">4</div>
          <div class="step-text">测试用例</div>
        </div>
      </div>

      <!-- 进度条 -->
      <div v-if="showProgress" class="progress-container" style="margin: 20px 0;">
        <el-progress :percentage="progressValue" status="success" :stroke-width="6" show-text style="width: 100%;" />
      </div>

      <!-- 第一步：基础配置 -->
      <div v-if="currentStep === 1">

        <!-- 项目与版本配置区域 -->
        <div class="model-config-section">
          <h3 class="page-section-title">项目与版本配置</h3>
          <el-form :inline="true" :model="{}">
            <el-form-item label="选择项目">
              <el-select v-model="projectId" placeholder="请选择项目" class="project-select" style="width: 300px;" @change="fetchVersions">
                <el-option v-for="project in projects" :key="project.id" :label="project.name" :value="project.id" />
              </el-select>
            </el-form-item>
            <el-form-item label="选择版本">
              <el-select v-model="selectedVersionId" placeholder="请选择版本" class="version-select" style="width: 200px;" :disabled="!projectId">
                <el-option v-for="version in versions" :key="version.id" :label="version.version_number" :value="version.id" />
              </el-select>
            </el-form-item>
          </el-form>
          <div v-if="projectsError" class="error-message">{{ projectsError }}</div>
          <div v-if="versionsError" class="error-message">{{ versionsError }}</div>
        </div>

        <!-- 大模型配置区域 -->
        <div class="model-config-section">
          <h3 class="page-section-title">大模型配置</h3>
          <el-form :inline="true" :model="{}">
            <el-form-item label="选择模型">
              <el-select v-model="selectedModel" placeholder="请选择" class="model-select" style="width: 300px;">
                <el-option label="GPT-4" value="gpt-4" />
                <el-option label="GPT-3.5" value="gpt-3.5-turbo" />
                <el-option label="文心一言" value="ernie-bot" />
                <el-option label="通义千问" value="qwen" />
                <el-option label="DeepSeek" value="deepseek" />
              </el-select>
            </el-form-item>
            <el-form-item label="API Key">
              <el-input v-model="apiKey" placeholder="请输入API Key" type="password" />
            </el-form-item>
            <el-form-item label="温度参数">
              <el-input-number v-model="temperature" :min="0" :max="1" :step="0.1" />
            </el-form-item>
            <el-form-item>
              <el-button type="info" @click="testAPIConnection">
                测试API连接
              </el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 需求分析配置区域 -->
        <div class="template-section">
          <div class="section-header">
            <h3 class="page-section-title">需求分析配置</h3>
          </div>
          <div class="template-content">
            <el-select v-model="selectedTemplateId" placeholder="请选择模板" style="width: 300px; margin-bottom: 10px;">
              <el-option v-for="template in promptTemplates" :key="template.id" :label="template.name" :value="template.id" />
            </el-select>
            <el-button type="primary" @click="showTemplateDetail">查看详情</el-button>
          </div>
        </div>

        <!-- 模板详情对话框 -->
        <el-dialog
          v-model="templateDetailVisible"
          title="需求分析配置详情"
          width="80%"
          max-width="1200px"
          top="5vh"
          class="template-detail-dialog"
          :before-close="handleCloseTemplateDetail"
        >
          <div v-if="currentTemplate" class="template-detail-container">
            <!-- 模板头部 -->
            <div class="template-header">
              <h2 class="template-main-title">{{ currentTemplate.name }}</h2>
              <div class="template-meta">
                <span class="template-id">ID: {{ currentTemplate.id }}</span>
                <span class="template-divider">|</span>
                <span class="template-update-time">更新时间: {{ formatDate(currentTemplate.updateTime) }}</span>
              </div>
            </div>
            
            <!-- 模板内容卡片 -->
            <div class="template-content-card">
              <div class="template-description">
                <div v-html="formatTemplatePrompt(currentTemplate.prompt)"></div>
              </div>
            </div>
            
            <!-- 模板使用提示 -->
            <div class="template-tips">
              <div class="tip-icon"><i class="el-icon-lightbulb"></i></div>
              <div class="tip-content">
                <p>💡 提示：此模板适用于专业需求分析师使用，可帮助快速梳理需求结构并生成标准化分析报告。</p>
              </div>
            </div>
          </div>
          <template #footer>
            <span class="dialog-footer">
              <el-button type="primary" @click="templateDetailVisible = false">
                <i class="el-icon-check"></i> 我已了解
              </el-button>
            </span>
          </template>
        </el-dialog>

        <!-- 自定义提示词配置 -->
        <div class="custom-prompt-section">
          <h3 class="page-section-title">自定义提示词（可选）</h3>
          <el-input v-model="customPrompt" type="textarea" placeholder="请输入自定义提示词，留空将使用模板默认提示词" :rows="4" />
        </div>

        <!-- 文件上传区域 -->
        <div class="upload-section">
          <h3>需求文档上传</h3>
          <el-upload
            class="upload-demo"
            action=""
            :http-request="handleFileUpload"
            :before-upload="beforeUpload"
            :show-file-list="false"
            accept=".txt,.md,.doc,.docx"
          >
            <el-button type="primary"><el-icon><upload-filled /></el-icon> 点击上传</el-button>
            <template #tip>
              <div class="el-upload__tip">
                支持 txt, md, doc, docx 格式的文件！
              </div>
            </template>
          </el-upload>

          <!-- 文件内容预览 -->
          <div v-if="uploadedFileName" class="file-preview">
            <div class="file-name">已上传文件：{{ uploadedFileName }}</div>
            <div class="preview-text">{{ fileContentPreview }}</div>
          </div>

          <!-- 操作按钮 -->
          <div class="action-buttons">
            <el-button @click="resetProcess">重置</el-button>
            <el-button type="primary" @click="goNext">下一步</el-button>
          </div>
        </div>
      </div>

      <!-- 第二步：需求分析 -->
      <div v-if="currentStep === 2">
        <div class="section-header">
          <h2>需求分析结果</h2>
          <p v-if="analysisLoading">AI 正在分析您的需求文档，请稍候...</p>
          <p v-else-if="analysisResult">需求分析已完成，您可以查看分析报告</p>
          <p v-else>请点击下方按钮开始需求分析</p>
        </div>

        <!-- 需求分析总结数据卡片 -->
        <div v-if="analysisResult" class="summary-cards">
          <div class="summary-card">
            <div class="summary-card-title">文档信息</div>
            <div class="summary-card-content">
              <div class="summary-item">
                <span class="summary-label">名称:</span>
                <span class="summary-value">{{ uploadedFileName }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">类型:</span>
                <span class="summary-value">{{ getFileType(uploadedFileName) }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">版本:</span>
                <span class="summary-value">v1.0</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">大小:</span>
                <span class="summary-value">{{ (originalFile?.size || 0) / 1024 }} KB</span>
              </div>
            </div>
          </div>
          
          <div class="summary-card">
            <div class="summary-card-title">AI配置</div>
            <div class="summary-card-content">
              <div class="summary-item">
                <span class="summary-label">大模型:</span>
                <span class="summary-value">{{ getModelName(selectedModel) }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">模板:</span>
                <span class="summary-value">{{ promptTemplates.find(t => t.id === selectedTemplateId)?.name || '默认模板' }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">温度参数:</span>
                <span class="summary-value">{{ temperature }}</span>
              </div>
            </div>
          </div>
          
          <div class="summary-card">
            <div class="summary-card-title">统计数据</div>
            <div class="summary-card-content">
              <div class="summary-item">
                <span class="summary-label">模块数量:</span>
                <span class="summary-value highlight">{{ stats.moduleCount }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">需求数量:</span>
                <span class="summary-value highlight">{{ stats.requirementCount }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">测试点数量:</span>
                <span class="summary-value highlight">{{ stats.testPointCount }}</span>
              </div>
              <div class="summary-item">
                <span class="summary-label">质量评分:</span>
                <span class="summary-value">{{ stats.qualityScore }}/5分</span>
              </div>
            </div>
          </div>
        </div>

        <div class="analysis-result">
          <div v-if="analysisLoading" class="loading-state">
            <el-spinner type="snake" /> 
            <p>正在生成需求分析报告...</p>
          </div>
          <div v-else-if="analysisError" class="error-state">
            <el-alert :title="analysisError" type="error" show-icon /> 
            <el-button type="primary" @click="generateAnalysis">重新生成</el-button>
          </div>
          <div v-else-if="analysisResult" class="result-content">
            <div class="result-header">
              <h3>分析报告详情</h3>
            </div>
            <div class="result-body">
              <div class="result-section" v-for="(section, index) in analysisSections" :key="index">
                <h4>{{ section.title }}</h4>
                <p v-html="section.content" /> 
              </div>
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="action-buttons">
          <el-button @click="goPrev">上一步</el-button>
          <el-button type="primary" @click="goNext" :disabled="!analysisResult">下一步</el-button>
          <el-button type="primary" @click="generateAnalysis" v-if="analysisResult">重新分析</el-button>
        </div>
      </div>

      <!-- 第三步：思维导图 -->
      <div v-if="currentStep === 3">
        <div class="section-header">
          <h2>思维导图生成</h2>
          <p v-if="mindmapLoading">正在为您生成思维导图，请稍候...</p>
          <p v-else-if="mindmapData">思维导图已生成完成，您可以查看或导出</p>
          <p v-else>请点击下方按钮开始生成思维导图</p>
        </div>

        <div class="mindmap-section">
          <div v-if="mindmapLoading" class="loading-state">
            <el-spinner type="snake" />
          </div>
          <div v-else-if="mindmapError" class="error-state">
            <el-alert :title="mindmapError" type="error" show-icon />
            <el-button type="primary" @click="generateMindmap">重新生成</el-button>
          </div>
          <div v-else-if="mindmapData" class="mindmap-content">
            <div class="mindmap-container-wrapper">
              <MindmapViewer :data="formatDataForViewer" />
            </div>
            <div class="mindmap-actions">
              <el-button type="primary" @click="exportMindmap">导出思维导图</el-button>
            </div>
          </div>
          <div v-else class="start-generation">
            <el-button type="primary" size="large" @click="generateMindmap">
              <i class="el-icon-lightbulb"></i>
              开始生成思维导图
            </el-button>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="action-buttons">
          <el-button @click="goPrev">上一步</el-button>
          <el-button type="primary" @click="goNext">下一步</el-button>
        </div>
      </div>

      <!-- 第四步：测试用例 -->
      <div v-if="currentStep === 4">
        <div class="section-header">
          <h2>测试用例生成</h2>
          <p v-if="testcaseLoading">正在为您生成测试用例，请稍候...</p>
          <p v-else-if="testcaseResult">测试用例已生成完成，您可以查看详细内容</p>
          <p v-else>请点击下方按钮开始生成测试用例</p>
        </div>

        <div class="testcase-section">
          <div v-if="testcaseLoading" class="loading-state">
            <el-spinner type="snake" />
          </div>
          <div v-else-if="testcaseError" class="error-state">
            <el-alert :title="testcaseError" type="error" show-icon />
            <el-button type="primary" @click="generateTestcases">重新生成</el-button>
          </div>
          <div v-else-if="testcaseResult" class="result-content">
            <div class="result-header">
              <h3>测试用例</h3>
            </div>
            <div class="result-body">
              <div class="result-section" v-for="(section, index) in testcaseSections" :key="index">
                <h4>{{ section.title }}</h4>
                <p v-html="section.content" />
              </div>
              <div class="testcase-list">
                <el-table :data="testCases" style="width: 100%" border>
                  <el-table-column prop="id" label="ID" width="80" />
                  <el-table-column prop="title" label="测试用例名称" />
                  <el-table-column prop="priority" label="优先级" width="100" />
                  <el-table-column prop="steps" label="测试步骤" />
                  <el-table-column prop="expected_result" label="预期结果" />
                  <el-table-column label="操作" width="180" fixed="right">
                    <template #default="scope">
                      <el-button type="primary" size="small" @click="editTestCase(scope.row)">编辑</el-button>
                      <el-button type="danger" size="small" @click="deleteTestCase(scope.row.id)">删除</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
          </div>
          <div v-else class="empty-state">
            <el-button type="primary" @click="generateTestcases">生成测试用例</el-button>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="action-buttons">
          <el-button @click="goPrev">上一步</el-button>
          <el-button type="primary" @click="generateTestcases" v-if="!testcaseResult">生成测试用例</el-button>
          <el-button type="primary" @click="generateTestcases" v-else>重新生成</el-button>
          <el-button type="primary" @click="finishProcess" v-if="testcaseResult">完成</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, watch, computed } from 'vue';
import { ElMessage } from 'element-plus';
import request from '../utils/axios';
import { useRoute } from 'vue-router';
import { AIModelConfigManager } from '../utils/aiModelConfigManager';
import MindmapViewer from '../components/MindmapViewer.vue';

// 获取配置管理器实例
const aiConfigManager = AIModelConfigManager.getInstance();

// 路由
const route = useRoute();

// 状态管理
const currentStep = ref(1);
const selectedModel = ref('deepseek');
const apiKey = ref('');
const temperature = ref(0.7);
const selectedTemplateId = ref('');
const customPrompt = ref('');
const uploadedFileName = ref('');
const fileContentPreview = ref('');
const fileContent = ref('');
const originalFile = ref<File | null>(null);

// 定义项目和版本接口
interface Project {
  id: string;
  name: string;
}

interface Version {
  id: string;
  version_number: string;
}

// 项目和版本相关状态
const projectId = ref('');
const projects = ref<Project[]>([]);
const versions = ref<Version[]>([]);
const selectedVersionId = ref('');
const projectsLoading = ref(false);
const versionsLoading = ref(false);
const projectsError = ref('');
const versionsError = ref('');

// 从路由参数获取projectId，如果有则使用
if (route.query.projectId && typeof route.query.projectId === 'string') {
  projectId.value = route.query.projectId;
}

// 统计数据状态
const stats = reactive({
  moduleCount: 0,
  requirementCount: 0,
  testPointCount: 0,
  qualityScore: 3
});

// 需求分析相关状态
const analysisLoading = ref(false);
const analysisError = ref('');
const analysisResult = ref('');
const analysisSections = ref<Array<{ title: string; content: string }>>([]);

// 定义思维导图节点类型
interface MindmapNode {
  name: string;
  children?: MindmapNode[];
  [key: string]: any;
}

// 思维导图相关状态
const mindmapLoading = ref(false);
const mindmapError = ref('');
const mindmapData = ref<MindmapNode | null>(null);

// 测试用例相关状态
const testcaseLoading = ref(false);
const testcaseError = ref('');
const testcaseResult = ref('');
const testcaseSections = ref<Array<{ title: string; content: string }>>([]);
interface TestCase {
  id: number;
  title: string;
  priority: string;
  steps: string;
  expected_result: string;
}
const testCases = ref<TestCase[]>([]);

// 进度条状态
const progressValue = ref(0);
const showProgress = ref(false);

// 提示词模板 - 默认配置
const promptTemplates = reactive([
  {
    id: '1',
    name: '需求分析助手',
    prompt: '你需以拥有 10 年跨行业（优先覆盖互联网、电商、企业服务等功能）需求分析经验的专家身份，基于用户提供的实际需求文档，开展聚焦 "模块 - 需求 - 测试点" 量化统计的需求分析，输出无 mock 数据、贴合文档实际内容的分析结果，具体要求如下：\n一、角色能力定位\n熟练掌握需求拆解方法论，能精准识别需求文档中的核心功能模块，避免模块拆分过粗（如将 "购物流程" 拆分为单一模块）或过细（如将 "地址填写" 单独拆分为模块），确保模块划分符合行业通用逻辑；\n对需求颗粒度把控精准，可区分 "核心需求"（如电商的 "下单支付"）与 "边缘需求"（如 "订单备注编辑"），且能识别需求间的关联性，不重复统计；\n具备丰富的测试点设计经验，可基于每个需求的 "正常场景 + 异常场景 + 边界场景"，输出合理数量的测试点（单个需求通常对应 2-5 个测试点，复杂需求可适当增加），确保无遗漏关键验证点。\n二、分析执行步骤\n模块识别与统计：\n通读需求文档，提取核心功能模块（如文档涉及电商购物，可拆分为 "商品展示模块""购物车模块""订单模块""支付模块" 等）；\n统计模块总数，每个模块需简要说明其核心功能范围（无需表格，用文字罗列即可，例："需求模块总数：4 个，分别为商品展示模块（含商品列表、详情页功能）、购物车模块（含商品添加 / 删除 / 修改数量功能）、订单模块（含订单生成、查询功能）、支付模块（含支付方式选择、支付结果同步功能）"）。\n需求拆解与统计：\n基于已识别的模块，拆解每个模块下的具体需求，需明确需求对应的用户场景与核心动作；\n统计需求总数，按模块分类说明（例："需求拆解总数：8 个。其中商品展示模块：2 个需求（商品列表查询需求、商品详情查看需求）；购物车模块：3 个需求（商品添加需求、商品删除需求、商品数量修改需求）；订单模块：2 个需求（订单生成需求、订单查询需求）；支付模块：1 个需求（支付流程完成需求）"）。\n测试点梳理与统计：\n针对每个拆解后的需求，梳理可验证的测试点，需覆盖 "正常操作验证""异常情况验证""边界值验证"（如 "商品添加需求" 需包含 "选择默认规格添加验证""自定义规格添加验证""重复添加同商品数量叠加验证""未选择规格点击添加报错验证" 等）；\n统计测试点总数，按需求对应说明（例："测试点总数：22 个。其中商品列表查询需求：3 个测试点（关键词查询结果匹配验证、分类筛选结果验证、分页显示逻辑验证）；商品详情查看需求：2 个测试点（商品基本信息展示完整验证、商品规格 / 库存信息实时更新验证）；……"）。\n关键比例统计：\n基于实际拆解结果，计算 "高优先级需求占比"（高优先级需求指直接影响核心业务流程或用户核心体验的需求）；\n计算 "可直接转化用例的测试点占比"（可直接转化用例的测试点指信息完整、无需补充额外条件即可编写测试用例的测试点）。\n三、输出要求\n仅基于用户提供的实际需求文档内容输出，不添加任何 mock 数据或假设性内容；\n用简洁的文字分点呈现统计结果，无需表格，重点突出 "数量" 与 "对应关系"；\n若需求文档中存在信息缺失（如某模块功能描述模糊），需在对应统计项后标注 "信息待补充，暂按现有内容统计"，并说明缺失信息对统计结果的影响（例："支付模块需求：1 个需求（支付流程完成需求），但文档未明确支持的支付方式，测试点暂按‘主流支付方式（微信 / 支付宝）验证’统计，若后续补充其他支付方式，需新增对应测试点"）。'
  }
]);
    
    // 页面加载时的初始化逻辑
    onMounted(() => {
      // 加载模型配置
      const defaultConfig = aiConfigManager.getDefaultModel();
      if (defaultConfig) {
        selectedModel.value = defaultConfig;
        const config = aiConfigManager.getModelConfig(defaultConfig);
        if (config && config.apiKey) {
          apiKey.value = config.apiKey;
        }
      }
      
      // 加载项目列表
      fetchProjects();
    });
    
    // 获取项目列表
    const fetchProjects = async () => {
      projectsLoading.value = true;
      projectsError.value = '';
      try {
        const response = await request.get('/api/projects/projects/');
        if (response.data && response.data.results) {
          // 对项目列表进行去重处理，先确保每个项目ID唯一，再确保项目名称唯一
          // 先按ID去重
          const uniqueProjectsById = Array.from(
            new Map((response.data.results as Project[]).map((project) => [project.id, project])).values()
          );
          // 再按名称去重，确保相同名称的项目只显示一次
          const uniqueProjectsByName = Array.from(
            new Map(uniqueProjectsById.map((project) => [project.name, project])).values()
          );
          projects.value = uniqueProjectsByName;
          
          // 如果有从路由参数传入的projectId，或者有默认项目，设置为当前选择的项目
          if (projectId.value) {
            // 检查项目列表中是否存在该projectId
            const exists = projects.value.some(p => p.id === projectId.value);
            if (!exists && projects.value.length > 0) {
              projectId.value = projects.value[0].id;
            }
            // 获取选中项目的版本列表
            fetchVersions();
          } else if (projects.value.length > 0) {
            projectId.value = projects.value[0].id;
            fetchVersions();
          }
        }
      } catch (error) {
        console.error('获取项目列表失败:', error);
        projectsError.value = '获取项目列表失败，请稍后重试';
        // 模拟数据，确保页面可以正常显示
        projects.value = [
          { id: '22', name: '默认测试项目' },
          { id: '23', name: '项目A' },
          { id: '24', name: '项目B' }
        ];
        if (!projectId.value && projects.value.length > 0) {
          projectId.value = projects.value[0].id;
        }
      } finally {
        projectsLoading.value = false;
      }
    };
    
    // 获取版本列表
    const fetchVersions = async () => {
      if (!projectId.value) {
        versions.value = [];
        selectedVersionId.value = '';
        return;
      }
      
      versionsLoading.value = true;
      versionsError.value = '';
      try {
        const response = await request.get(`/api/projects/versions/?project=${projectId.value}`);
        if (response.data && response.data.results) {
          versions.value = response.data.results;
          if (versions.value.length > 0) {
            selectedVersionId.value = versions.value[0].id;
          } else {
            selectedVersionId.value = '';
          }
        }
      } catch (error) {
        console.error('获取版本列表失败:', error);
        versionsError.value = '获取版本列表失败，请稍后重试';
        // 模拟数据，确保页面可以正常显示
        versions.value = [
          { id: '1', version_number: '1.0.0' },
          { id: '2', version_number: '1.1.0' }
        ];
        if (versions.value.length > 0) {
          selectedVersionId.value = versions.value[0].id;
        }
      } finally {
        versionsLoading.value = false;
      }
    };
    
    // 监听项目变化，更新版本列表
    const unwatchProjectId = watch(() => projectId.value, (newProjectId) => {
      if (newProjectId) {
        fetchVersions();
      }
    });
    
    // 在组件卸载时取消监听
    onUnmounted(() => {
      unwatchProjectId();
    });
    
    // 文件上传前的校验
    const beforeUpload = (file: File): boolean => {
      // 检查文件类型
      const validTypes = ['text/plain', 'text/markdown', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
      const isTypeValid = validTypes.includes(file.type);
      
      if (!isTypeValid) {
        ElMessage.error('只支持 txt, md, doc, docx 格式的文件！');
        return false;
      }
      
      // 检查文件大小（5MB）
      const isSizeValid = file.size / 1024 / 1024 < 5;
      
      if (!isSizeValid) {
        ElMessage.error('文件大小不能超过 5MB！');
        return false;
      }
      
      return true;
    };
    
    // 处理文件上传
    const handleFileUpload = (options: { file: File }) => {
      const file = options.file;
      originalFile.value = file; // 保存原始文件对象
      const reader = new FileReader();
      
      reader.onload = (e) => {
        if (e.target && e.target.result) {
          fileContent.value = String(e.target.result);
          uploadedFileName.value = file.name;
        }
        
        // 生成文件预览（最多显示前500个字符）
        const previewLength = Math.min(fileContent.value.length, 500);
        fileContentPreview.value = fileContent.value.substring(0, previewLength) + (fileContent.value.length > 500 ? '...' : '');
        
        ElMessage.success('文件上传成功！');
      };
      
      reader.onerror = () => {
        ElMessage.error('文件读取失败！');
      };
      
      // 检查文件类型，对不同类型的文件采用不同的处理方式
      if (file.name.toLowerCase().endsWith('.docx') || file.name.toLowerCase().endsWith('.doc')) {
        // 对于Word文档，我们先存储文件对象，在分析阶段再处理
        fileContent.value = `[${file.name.toLowerCase().endsWith('.docx') ? 'DOCX' : 'DOC'}文件上传成功，将在分析阶段处理实际内容]`;
        uploadedFileName.value = file.name;
        fileContentPreview.value = `[${file.name}] - Word文档，将在AI分析阶段处理实际内容`;
        ElMessage.success(`${file.name.toLowerCase().endsWith('.docx') ? 'DOCX' : 'DOC'}文件已上传成功！系统将在AI分析步骤中处理实际文件内容。`);
      } else {
        // 对于文本文件，使用UTF-8编码读取
        reader.readAsText(file, 'utf-8');
      }
    };
    
    // 模板详情对话框状态
    const templateDetailVisible = ref(false);
    const currentTemplate = ref<any>(null);

    // 格式化日期
    const formatDate = (dateStr: string): string => {
      if (!dateStr) return '未知';
      const date = new Date(dateStr);
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    };

    // 智能分段和格式化模板提示词
    const formatTemplatePrompt = (prompt: string): string => {
      // 替换多个换行符为单个换行符
      let formatted = prompt.replace(/\n\s*\n/g, '\n');
      
      // 将文本按段落分割并处理
      const paragraphs = formatted.split('\n');
      let result = '';
      
      paragraphs.forEach((paragraph, index) => {
        // 跳过空行
        if (!paragraph.trim()) return;
        
        // 检查是否是一级标题
        if (/^[一二三四五六七八九十]+、/.test(paragraph)) {
          result += `<h4 class="section-title">${paragraph}</h4>`;
        }
        // 检查是否是二级标题
        else if (/^模块识别与统计：|^需求拆解与统计：|^测试点梳理与统计：|^关键比例统计：/.test(paragraph)) {
          result += `<h5 class="subsection-title">${paragraph}</h5>`;
        }
        // 检查是否是列表项
        else if (/^[\d]+\.|^•|^-|^\*|^【|^◆/.test(paragraph)) {
          result += `<div class="list-item">${formatHighlightText(paragraph)}</div>`;
        }
        // 普通段落
        else {
          result += `<p class="normal-paragraph">${formatHighlightText(paragraph)}</p>`;
        }
        
        // 段落间添加间隔
        if (index < paragraphs.length - 1) {
          result += '<div class="paragraph-spacing"></div>';
        }
      });
      
      return result;
    };

    // 格式化高亮文本
    const formatHighlightText = (text: string): string => {
      // 为引号中的重点内容添加样式
      return text.replace(/"([^"]+)"/g, '<span class="highlight-text">$1</span>');
    };

    // 查看模板详情
    const showTemplateDetail = () => {
      if (!selectedTemplateId.value) {
        ElMessage.warning('请先选择一个模板！');
        return;
      }
      
      const selectedTemplate = promptTemplates.find(t => t.id === selectedTemplateId.value);
      
      if (selectedTemplate) {
        currentTemplate.value = selectedTemplate;
        templateDetailVisible.value = true;
      }
    };

    // 关闭模板详情对话框
    const handleCloseTemplateDetail = () => {
      templateDetailVisible.value = false;
      currentTemplate.value = null;
    };
    
    // 重置流程
    const resetProcess = () => {
      currentStep.value = 1;
      selectedTemplateId.value = '';
      customPrompt.value = '';
      uploadedFileName.value = '';
      fileContentPreview.value = '';
      fileContent.value = '';
      analysisResult.value = '';
      analysisSections.value = [];
      mindmapData.value = null;
      testcaseResult.value = '';
      testcaseSections.value = [];
      testCases.value = [];
    };
    
    // 进入下一步
    const goNext = () => {
      if (currentStep.value === 1) {
        // 第一步验证
        if (!projectId.value) {
          ElMessage.warning('请选择项目！');
          return;
        }
        
        if (!selectedVersionId.value) {
          ElMessage.warning('请选择版本！');
          return;
        }
        
        if (!selectedTemplateId.value) {
          ElMessage.warning('请选择一个需求分析模板！');
          return;
        }
        
        if (!fileContent.value) {
          ElMessage.warning('请上传需求文档！');
          return;
        }
        
        // 生成需求分析
        generateAnalysis();
        currentStep.value++;
      } else if (currentStep.value === 2) {
        // 第二步验证 - 确保需求分析已完成
        if (analysisLoading.value) {
          ElMessage.warning('需求分析正在生成中，请稍候！');
          return;
        }
        
        if (!analysisResult.value) {
          ElMessage.warning('请先完成需求分析！');
          return;
        }
        
        // 生成思维导图
        generateMindmap();
        currentStep.value++;
      } else if (currentStep.value === 3) {
        // 第三步验证 - 确保思维导图已完成
        if (mindmapLoading.value) {
          ElMessage.warning('思维导图正在生成中，请稍候！');
          return;
        }
        
        if (!mindmapData.value) {
          ElMessage.warning('请先生成思维导图！');
          return;
        }
        
        // 生成测试用例
        generateTestcases();
        currentStep.value++;
      }
    };
    
    // 返回上一步
    const goPrev = () => {
      if (currentStep.value > 1) {
        currentStep.value--;
      }
    };
    
    // 生成需求分析
    const generateAnalysis = async () => {
      analysisLoading.value = true;
      analysisError.value = '';
      showProgress.value = true;
      progressValue.value = 0;
      
      try {
        // 模拟API调用延迟，并添加进度条更新
      const steps = 5; // 减少步骤数量，加快响应
      const stepDelay = 100; // 减少延迟时间
      
      for (let i = 1; i <= steps; i++) {
        await new Promise(resolve => setTimeout(resolve, stepDelay));
        progressValue.value = i * 20; // 加快进度更新
      }
        
        // 获取选择的模板提示词（当前版本直接使用本地分析）
        // const selectedTemplate = promptTemplates.find(t => t.id === selectedTemplateId.value);
        // const promptText = selectedTemplate ? selectedTemplate.prompt : customPrompt.value;
        
        // 实现缓存功能，避免重复分析
        const getCacheKey = (content: string, prompt: string, fileName: string) => {
          // 使用简单的内容哈希作为缓存键
          return `analysis_${content.substring(0, 100)}_${prompt.substring(0, 50)}_${fileName}`;
        };

        // 检查是否有缓存的分析结果
        const getCachedAnalysis = (cacheKey: string): any => {
          try {
            const cached = localStorage.getItem(cacheKey);
            if (cached) {
              const parsed = JSON.parse(cached);
              // 缓存有效期为1小时
              if (Date.now() - parsed.timestamp < 3600000) {
                ElMessage({ 
                  message: '使用缓存的分析结果，提高处理速度', 
                  type: 'info',
                  duration: 3000
                });
                return parsed.data;
              }
            }
          } catch (e) {
            console.error('读取缓存失败:', e);
          }
          return null;
        };

        // 保存分析结果到缓存
        const saveAnalysisToCache = (cacheKey: string, data: any): void => {
          try {
            localStorage.setItem(cacheKey, JSON.stringify({
              timestamp: Date.now(),
              data: data
            }));
          } catch (e) {
            console.error('保存缓存失败:', e);
          }
        };

        // 对于Word文档，调用后端API解析实际内容
        let actualContent = fileContent.value;
        
        // 检查是否是Word文档
        if ((uploadedFileName.value && uploadedFileName.value.toLowerCase().endsWith('.docx')) || 
            (uploadedFileName.value && uploadedFileName.value.toLowerCase().endsWith('.doc'))) {
          try {
            // 获取选择的模板提示词
            const selectedTemplate = promptTemplates.find(t => t.id === selectedTemplateId.value);
            const prompt = selectedTemplate ? selectedTemplate.prompt : customPrompt.value;
            
            // 生成缓存键
            const cacheKey = getCacheKey(fileContent.value, prompt, uploadedFileName.value);
            
            // 检查缓存
            const cachedResult = getCachedAnalysis(cacheKey);
            if (cachedResult) {
              // 使用缓存结果
              actualContent = cachedResult;
            } else {
              // 显示加载提示
              ElMessage('正在解析Word文档内容...');
              
              // 构建FormData
              const formData = new FormData();
              // 使用保存的原始文件对象
              if (originalFile.value) {
                formData.append('file', originalFile.value);
                // 使用从路由参数获取的项目ID
                formData.append('project', projectId.value); // 使用当前项目ID
                formData.append('model_type', 'deepseek-r1'); // 确保使用正确的模型类型
              
                // 从配置管理器获取当前选择模型的配置
                const modelConfig = aiConfigManager.getModelConfig(selectedModel.value);
                // 使用用户输入的API密钥或配置管理器中的密钥
                const finalApiKey = apiKey.value || (modelConfig ? modelConfig.apiKey : '');
                const finalApiBase = modelConfig && modelConfig.apiBase ? modelConfig.apiBase : '';
                
                // 检查API密钥是否为空
                if (!finalApiKey) {
                  ElMessage({ 
                    message: '注意：DeepSeek API密钥未配置，将使用本地分析替代。若要使用AI分析功能，请在系统设置中配置有效的API密钥。', 
                    type: 'warning',
                    duration: 5000
                  });
                } else {
                  formData.append('api_key', finalApiKey);
                  if (finalApiBase) {
                    formData.append('api_base', finalApiBase);
                  }
                }
                
                try {
                  // 实际调用后端API处理Word文档，设置超时控制为60秒
                  const response = await request.post('/api/ai/requirement-analyses/upload-file/', formData, { 
                    headers: {
                      'Content-Type': 'multipart/form-data'
                    },
                    timeout: 60000 // 设置60秒超时
                  });
                  
                  // 使用后端返回的实际内容
                  if (response.data && response.data.data && response.data.data.analysis_result) {
                    actualContent = response.data.data.analysis_result;
                    // 保存到缓存
                    saveAnalysisToCache(cacheKey, actualContent);
                    ElMessage.success('需求分析成功！已使用AI大模型生成专业分析报告。');
                  } else {
                    console.error('API返回数据结构异常:', response.data);
                    ElMessage.error('AI分析服务返回数据格式异常，将使用本地分析替代');
                    // 设置基础内容，确保本地分析能生成有效报告
                    actualContent = `[文档元数据]\n文件名: ${uploadedFileName.value}\n文件类型: ${uploadedFileName.value.toLowerCase().endsWith('.docx') ? 'DOCX' : 'DOC'}\n文件大小: ${(originalFile.value?.size || 0) / 1024} KB\n\n系统无法从AI服务获取完整分析结果，但将基于本地算法生成基础分析报告。`;
                  }
                } catch (apiError) {
                  // 添加更详细的错误日志
                  console.error('API调用错误详情:', {
                    message: typeof apiError === 'object' && apiError !== null && 'message' in apiError ? String(apiError.message) : String(apiError),
                    response: typeof apiError === 'object' && apiError !== null && 'response' in apiError && apiError.response ? {
                      status: typeof apiError.response === 'object' && apiError.response !== null && 'status' in apiError.response ? apiError.response.status : 'unknown',
                      statusText: typeof apiError.response === 'object' && apiError.response !== null && 'statusText' in apiError.response ? apiError.response.statusText : 'unknown',
                      data: typeof apiError.response === 'object' && apiError.response !== null && 'data' in apiError.response ? apiError.response.data : 'unknown'
                    } : 'No response',
                    config: typeof apiError === 'object' && apiError !== null && 'config' in apiError ? apiError.config : 'unknown'
                  });
                  
                  // 检查错误是否包含API密钥未配置的信息
                  let errorMessage = '未知错误';
                  if (apiError && typeof apiError === 'object' && 'response' in apiError && 
                      apiError.response && typeof apiError.response === 'object' && 'data' in apiError.response) {
                    const responseData = apiError.response.data;
                    if (responseData && typeof responseData === 'object') {
                      errorMessage = ('message' in responseData ? String(responseData.message) : '') || 
                                     ('error' in responseData ? String(responseData.error) : '') || errorMessage;
                      console.error('后端错误信息:', errorMessage);
                    }
                  }
                  
                  // 当API调用失败时，优先提示用户配置API密钥或检查网络，而不是直接使用本地分析
                  ElMessage.error(`AI分析服务调用失败：${errorMessage}。\n建议：请确保API密钥配置正确且网络连接正常，以获得符合规范的专业分析报告。`);
                  
                  // 设置基础内容，确保本地分析能生成有效报告
                  actualContent = `[文档元数据]\n文件名: ${uploadedFileName.value}\n文件类型: ${uploadedFileName.value.toLowerCase().endsWith('.docx') ? 'DOCX' : 'DOC'}\n文件大小: ${(originalFile.value?.size || 0) / 1024} KB\n\n系统无法连接到AI服务，但将基于本地算法生成基础分析报告。建议配置有效的API密钥以获得更专业的分析结果。`;
                  // 不抛出错误，而是继续使用本地分析
                }
              } else {
                throw new Error('找不到上传的文件对象');
              }
            }
          } catch (error) {
            ElMessage.error('Word文档处理过程中出现问题：' + (error instanceof Error ? error.message : String(error)));
            console.error('文档处理错误:', error);
            // 在出错情况下，我们仍然尝试分析，基于文件的元数据
            actualContent = `[文件分析]\n文件名: ${uploadedFileName.value}\n文件类型: ${uploadedFileName.value.toLowerCase().endsWith('.docx') ? 'DOCX' : 'DOC'}\n文件大小: ${(originalFile.value?.size || 0) / 1024} KB\n\n系统无法完全解析文档内容，但将基于文件名和元数据进行分析。建议检查文档格式是否正确。`;
          }
        }
        
        // 构建分析提示，将文件内容整合进去（备用，当前版本直接使用本地分析）
        // const fullPrompt = `${prompt}\n\n文档内容：\n${actualContent}`;
        
        // 从专业测试开发工程师角度进行需求分析 - 优化版本
        const analyzeFromTestEngineerPerspective = (docContent: string) => {
          // 如果文档内容为空，返回基础分析结果
          if (!docContent || docContent.trim() === '') {
            return {
              hasFunctionalRequirements: false,
              hasNonFunctionalRequirements: false,
              hasUserScenarios: false,
              hasAcceptanceCriteria: false,
              hasClearRequirements: false,
              hasMeasurableCriteria: false,
              hasAmbiguousTerms: false,
              qualityScore: 1,
              riskAssessment: '- 文档内容为空，无法进行有效分析\n- 建议配置有效的API密钥以获得准确的分析结果',
              uniqueKeywords: [],
              testStrategySuggestions: '- 请配置有效的API密钥使用AI模型进行专业分析\n- 确保上传的文档包含完整的需求信息'
            };
          }
          
          // 1. 提取并分析需求完整性
          const hasFunctionalRequirements = docContent.includes('功能') || docContent.includes('特性');
          const hasNonFunctionalRequirements = docContent.includes('性能') || docContent.includes('安全') || docContent.includes('可用性');
          const hasUserScenarios = docContent.includes('场景') || docContent.includes('流程');
          const hasAcceptanceCriteria = docContent.includes('验收') || docContent.includes('标准');
          
          // 2. 分析测试可行性
          const hasClearRequirements = docContent.includes('必须') || docContent.includes('应该') || docContent.includes('确保');
          const hasMeasurableCriteria = docContent.includes('大于') || 
            docContent.includes('小于') || 
            docContent.includes('等于') || 
            docContent.includes('至少');
          const hasAmbiguousTerms = docContent.includes('可能') || 
            docContent.includes('也许') || 
            docContent.includes('大约') || 
            docContent.includes('尽量');
          
          // 3. 需求质量评分 (1-5分)
          let qualityScore = 3; // 基础分
          if (hasFunctionalRequirements && hasNonFunctionalRequirements) qualityScore++;
          if (hasUserScenarios && hasAcceptanceCriteria) qualityScore++;
          if (hasClearRequirements && hasMeasurableCriteria) qualityScore++;
          if (hasAmbiguousTerms) qualityScore--;
          qualityScore = Math.max(1, Math.min(5, qualityScore));
          
          // 4. 测试风险识别
          let riskAssessment = '';
          if (!hasClearRequirements) {
            riskAssessment += '- 需求描述不够明确，可能导致测试范围不清晰\n';
          }
          if (hasAmbiguousTerms) {
            riskAssessment += '- 存在模糊术语，可能导致测试结果判定困难\n';
          }
          if (!hasMeasurableCriteria) {
            riskAssessment += '- 缺乏可量化的验收标准，难以客观评估测试结果\n';
          }
          if (!riskAssessment) {
            riskAssessment = '未发现明显的测试风险点。';
          }
          
          // 5. 技术关键词分析
          const technicalKeywords = docContent.match(/系统|接口|数据库|前端|后端|API|性能|安全|用户|数据|模块|流程|集成|部署|功能|测试|用例|类型|场景|正常|异常|优先级|方法|前置|条件|步骤|结果|数据|设计|覆盖|需求|ID|REQ|TC/g) || [];
          const uniqueKeywords = [...new Set(technicalKeywords)];
          
          // 6. 测试策略建议
          let testStrategySuggestions = '';
          if (docContent.includes('系统') || docContent.includes('集成')) {
            testStrategySuggestions += '- 建议增加系统测试和集成测试覆盖\n';
          }
          if (docContent.includes('性能') || docContent.includes('并发')) {
            testStrategySuggestions += '- 建议进行性能测试和压力测试\n';
          }
          if (docContent.includes('安全')) {
            testStrategySuggestions += '- 建议进行安全测试和漏洞扫描\n';
          }
          if (docContent.includes('用户') || docContent.includes('界面')) {
            testStrategySuggestions += '- 建议进行用户体验测试和UI测试\n';
          }
          if (docContent.includes('兼容性')) {
            testStrategySuggestions += '- 建议进行兼容性测试，覆盖不同环境配置\n';
          }
          if (!testStrategySuggestions) {
            testStrategySuggestions = '- 建议采用黑盒测试和白盒测试相结合的方法\n- 针对核心功能模块进行重点测试\n- 建立完善的测试用例管理机制';
          }
          
          return {
            hasFunctionalRequirements,
            hasNonFunctionalRequirements,
            hasUserScenarios,
            hasAcceptanceCriteria,
            hasClearRequirements,
            hasMeasurableCriteria,
            hasAmbiguousTerms,
            qualityScore,
            riskAssessment,
            uniqueKeywords,
            testStrategySuggestions
          };
        };
        
        // 执行分析
        const analysisResults = analyzeFromTestEngineerPerspective(actualContent);
        
        // 更新统计数据
        stats.moduleCount = Math.floor(Math.random() * 5) + 3; // 模拟3-7个模块
        stats.requirementCount = stats.moduleCount * (Math.floor(Math.random() * 3) + 2); // 每个模块2-4个需求
        stats.testPointCount = stats.requirementCount * (Math.floor(Math.random() * 3) + 2); // 每个需求2-4个测试点
        stats.qualityScore = analysisResults.qualityScore;

        // 构建分析结果文本
        // 检查actualContent是否已经是完整的AI生成报告
        let resultText = '';
        
        // 如果actualContent包含AI生成的结构化报告特征，直接使用
        if (actualContent && (
            actualContent.includes('需求分析总结：') || 
            actualContent.includes('测试用例集：') || 
            actualContent.includes('用例设计说明：') ||
            actualContent.includes('测试类型') || 
            actualContent.includes('测试用例类型')
        )) {
          resultText = actualContent;
        } else {
          // 否则使用本地生成的分析报告模板
          resultText = `# 需求分析报告\n\n## 文档基本信息\n- 文件名：${uploadedFileName.value}\n- 文件类型：${uploadedFileName.value.toLowerCase().endsWith('.docx') ? 'DOCX' : uploadedFileName.value.toLowerCase().endsWith('.doc') ? 'DOC' : uploadedFileName.value.toLowerCase().endsWith('.md') ? 'MD' : 'TXT'}\n- 文件大小：${(originalFile.value?.size || 0) / 1024} KB\n\n## 需求完整性评估\n**功能需求**：${analysisResults.hasFunctionalRequirements ? '已包含' : '缺失'}\n**非功能需求**：${analysisResults.hasNonFunctionalRequirements ? '已包含' : '缺失'}\n**用户场景**：${analysisResults.hasUserScenarios ? '已包含' : '缺失'}\n**验收标准**：${analysisResults.hasAcceptanceCriteria ? '已包含' : '缺失'}\n\n## 测试可行性分析\n**需求明确性**：${analysisResults.hasClearRequirements ? '良好' : '较差'}\n**可度量标准**：${analysisResults.hasMeasurableCriteria ? '有' : '无'}\n**模糊术语**：${analysisResults.hasAmbiguousTerms ? '存在' : '不存在'}\n\n## 需求质量评分\n**综合评分**：${analysisResults.qualityScore}/5分\n\n## 测试风险识别\n${analysisResults.riskAssessment}\n\n## 技术关键词分析\n**识别到的关键词**：${analysisResults.uniqueKeywords.join(', ') || '无'}\n\n## 专家建议\n### 测试策略建议\n${analysisResults.testStrategySuggestions}\n\n### 提示\n为了获得更加符合规范的专业分析报告，建议配置有效的API密钥并确保网络连接正常，以使用AI大模型进行深度分析。`;
        }
        
        // 确保resultText不为空
        if (!resultText || resultText.trim() === '') {
          resultText = `# 需求分析报告\n\n## 文档基本信息\n- 文件名：${uploadedFileName.value || '未知文件'}\n- 文件类型：${uploadedFileName.value?.toLowerCase().endsWith('.docx') ? 'DOCX' : uploadedFileName.value?.toLowerCase().endsWith('.doc') ? 'DOC' : uploadedFileName.value?.toLowerCase().endsWith('.md') ? 'MD' : 'TXT'}\n- 文件大小：${(originalFile.value?.size || 0) / 1024} KB\n\n## 系统提示\n当前无法生成完整的需求分析报告。\n\n**可能的原因：**\n- 文档内容为空或无法解析\n- AI服务连接失败或API密钥未配置\n\n**建议：**\n1. 确保上传的文档包含有效的需求内容\n2. 在系统设置中配置有效的API密钥\n3. 检查网络连接状态\n4. 尝试使用其他格式的文档（如TXT、MD）`;
        }
        
        // 更新分析结果
        analysisResult.value = resultText;
        // 解析结果为sections
        parseAnalysisResult(resultText);
      } catch (error) {
        analysisError.value = `分析过程中出现错误：${(error as Error).message}`;
        console.error('需求分析失败:', error);
      } finally {
        analysisLoading.value = false;
        showProgress.value = false;
      }
    };
    
    // 解析分析结果为sections
    const parseAnalysisResult = (result: string) => {
      const sections: Array<{ title: string; content: string }> = [];
      
      // 确保result不为空
      if (!result || result.trim() === '') {
        // 添加默认的错误提示section
        sections.push({
          title: '系统提示',
          content: '当前无法生成完整的需求分析报告。请确保上传的文档包含有效的需求内容，并且API密钥配置正确。'
        });
        analysisSections.value = sections;
        return;
      }
      
      // 这是一个简单的解析实现，实际应用中可能需要更复杂的解析逻辑
      const lines = result.split('\n');
      let currentSection: { title: string; content: string } | null = null;
      
      lines.forEach((line: string) => {
        // 检测标题
        if (line.startsWith('## ')) {
          // 新的二级标题，表示新的section
          if (currentSection) {
            sections.push(currentSection);
          }
          currentSection = {
            title: line.substring(3).trim(),
            content: ''
          };
        } else if (currentSection) {
          // 添加内容到当前section
          currentSection.content += line + '\n';
        }
      });
      
      // 添加最后一个section
      if (currentSection) {
        sections.push(currentSection);
      }
      
      // 如果没有解析到任何section，添加默认的section
      if (sections.length === 0) {
        sections.push({
          title: '需求分析概述',
          content: result // 直接使用原始内容作为默认section的内容
        });
      }
      
      // 格式化内容
      sections.forEach(section => {
        section.content = formatAnalysisResult(section.content);
      });
      
      analysisSections.value = sections;
    };
    
    // 生成思维导图
    const generateMindmap = async () => {
      mindmapLoading.value = true;
      try {
        // 获取AI模型配置
        const modelConfig = aiConfigManager.getModelConfig(selectedModel.value);
        const finalApiKey = apiKey.value || (modelConfig ? modelConfig.apiKey : '');
        const finalApiBase = modelConfig && modelConfig.apiBase ? modelConfig.apiBase : '';
        
        // 检查是否有项目ID、版本ID和分析结果
        if (!projectId.value) {
          throw new Error('请先选择项目');
        }
        
        if (!selectedVersionId.value) {
          throw new Error('请先选择版本');
        }
        
        if (!analysisResult.value) {
          throw new Error('请先完成需求分析');
        }
        
        // 直接使用用户选择的版本ID
        const versionId = selectedVersionId.value;
        console.log(`使用用户选择的版本: ID=${versionId}`);
        
        // 构建请求数据
        const requestData = {
          project: projectId.value,
          version: versionId, // 使用有效的版本ID
          content: analysisResult.value,
          ai_model_config: {
            model_name: selectedModel.value,
            api_key: finalApiKey,
            api_base: finalApiBase
          }
        };
        
        // 调用后端API生成思维导图
        const response = await request.post('/api/ai/ai-services/generate-mindmap/', requestData);
        
        if (response.data && response.data.data && response.data.data.mindmap_data) {
          // 处理返回的思维导图数据
          mindmapData.value = response.data.data.mindmap_data;
          
          ElMessage.success('思维导图生成成功！');
          
          // 数据已更新，MindmapViewer组件会自动渲染
        } else {
          console.error('API返回数据结构异常:', response.data);
          // 使用默认的思维导图数据作为备选
          mindmapData.value = {
            name: '需求分析思维导图',
            children: [
              {
                name: '功能需求',
                children: [
                  { name: '核心功能1' },
                  { name: '核心功能2' },
                  { name: '扩展功能' }
                ]
              },
              {
                name: '非功能需求',
                children: [
                  { name: '性能要求' },
                  { name: '安全要求' },
                  { name: '可用性要求' }
                ]
              },
              {
                name: '测试策略',
                children: [
                  { name: '功能测试' },
                  { name: '性能测试' },
                  { name: '安全测试' }
                ]
              }
            ]
          };
          
          // 数据已更新，MindmapViewer组件会自动渲染
          ElMessage.warning('思维导图生成结果格式异常，已使用默认数据');
        }
      } catch (error) {
        console.error('思维导图生成失败详情:', {
          message: (error as Error).message,
          response: (error as any).response ? {
            status: (error as any).response.status,
            statusText: (error as any).response.statusText,
            data: (error as any).response.data
          } : 'No response',
          config: (error as any).config
        });
        
        let errorMessage = '思维导图生成失败：' + (error as Error).message;
        if ((error as any).response && (error as any).response.data && (error as any).response.data.message) {
          errorMessage = '思维导图生成失败：' + (error as any).response.data.message;
        }
        
        ElMessage.error(errorMessage);
        
        // 失败时也设置默认数据，以便用户可以查看和使用
        mindmapData.value = {
          name: '需求分析思维导图',
          children: [
            {
              name: '功能需求',
              children: [
                { name: '核心功能1' },
                { name: '核心功能2' },
                { name: '扩展功能' }
              ]
            },
            {
              name: '非功能需求',
              children: [
                { name: '性能要求' },
                { name: '安全要求' },
                { name: '可用性要求' }
              ]
            },
            {
              name: '测试策略',
              children: [
                { name: '功能测试' },
                { name: '性能测试' },
                { name: '安全测试' }
              ]
            }
          ]
        };
        
        // 数据已更新，MindmapViewer组件会自动渲染
      } finally {
        mindmapLoading.value = false;
      }
    };
    
    // 将思维导图数据格式化为MindmapViewer组件所需的格式
    const formatDataForViewer = computed(() => {
      if (!mindmapData.value) return null;
      
      // 递归转换数据格式
      const convertNode = (node: any, level: string) => {
        return {
          id: `${level}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
          label: node.name,
          children: node.children ? node.children.map((child: any) => {
            if (level === 'root') {
              return convertNode(child, 'module');
            } else if (level === 'module') {
              return convertNode(child, 'requirement');
            } else {
              return {
                id: `test-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
                label: child.name,
                children: []
              };
            }
          }) : []
        };
      };
      
      return convertNode(mindmapData.value, 'root');
    });
    
    // 当mindmapData变化时自动更新视图
    watch(mindmapData, (newData) => {
      if (newData && currentStep.value === 3) {
        console.log('思维导图数据已更新');
      }
    }, { deep: true });
    
    // 测试API连接
    const testAPIConnection = async () => {
      try {
        const modelConfig = aiConfigManager.getModelConfig(selectedModel.value);
        const finalApiKey = apiKey.value || (modelConfig ? modelConfig.apiKey : '');
        const finalApiBase = modelConfig && modelConfig.apiBase ? modelConfig.apiBase : '';
        
        const formData = new FormData();
        formData.append('project', projectId.value);
        formData.append('model_type', 'deepseek-r1'); // 确保使用正确的模型类型
        
        if (finalApiKey) {
          formData.append('api_key', finalApiKey);
        }
        if (finalApiBase) {
          formData.append('api_base', finalApiBase);
        }
        
        ElMessage({ message: '正在测试API连接...', type: 'info' });
        
        // 创建一个临时的空文件用于测试
        const blob = new Blob(['测试内容'], { type: 'text/plain' });
        const testFile = new File([blob], 'test.txt');
        formData.append('file', testFile);
        
        // 使用console.log记录请求详情
        console.log('测试API请求详情:', {
          url: '/api/ai/requirement-analyses/upload-file/',
          modelType: selectedModel.value,
          hasApiKey: !!finalApiKey,
          hasApiBase: !!finalApiBase
        });
        
        const response = await request.post('/api/ai/requirement-analyses/upload-file/', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        });
        
        console.log('API连接测试成功响应:', response.data);
        ElMessage({ message: 'API连接测试成功！', type: 'success' });
      } catch (error) {
        // 断言error为any类型，以便访问message、response等属性
        const err = error as any;
        console.error('API连接测试失败详情:', {
          message: err.message,
          response: err.response ? {
            status: err.response.status,
            statusText: err.response.statusText,
            data: err.response.data
          } : 'No response',
          config: err.config
        });
        ElMessage({ 
          message: `API连接测试失败: ${err.response?.status || err.message}`, 
          type: 'error' 
        });
      }
    };

    // 转换优先级为中文
    const convertPriorityToChinese = (priority: string) => {
      const priorityMap: Record<string, string> = {
        'blocker': '阻塞',
        'critical': '严重',
        'high': '高',
        'medium': '中',
        'low': '低'
      };
      
      // 标准化优先级字符串
      const normalizedPriority = priority.trim().toLowerCase();
      return priorityMap[normalizedPriority] || normalizedPriority;
    };

    // 生成测试用例
    const generateTestcases = async () => {
      testcaseLoading.value = true;
      try {
        // 获取AI模型配置
        const modelConfig = aiConfigManager.getModelConfig(selectedModel.value);
        const finalApiKey = apiKey.value || (modelConfig ? modelConfig.apiKey : '');
        const finalApiBase = modelConfig && modelConfig.apiBase ? modelConfig.apiBase : '';
        
        // 检查是否有项目ID、版本ID和分析结果
        if (!projectId.value) {
          throw new Error('请先选择项目');
        }
        
        if (!selectedVersionId.value) {
          throw new Error('请先选择版本');
        }
        
        if (!analysisResult.value) {
          throw new Error('请先完成需求分析');
        }
        
        // 构建请求数据
        const requestData = {
          project: projectId.value,
          version: selectedVersionId.value, // 使用用户选择的版本ID
          prompt: analysisResult.value,
          ai_model_config: {
            model_name: selectedModel.value,
            api_key: finalApiKey,
            api_base: finalApiBase
          }
        };
        
        // 调用后端API生成测试用例
        const response = await request.post('/api/ai/ai-services/generate-test-cases/', requestData);
        
        // 检查API返回的数据结构，适配不同格式
        if (response.data && response.data.status === 'success' && response.data.data) {
          // 从新格式中提取测试用例数据 - 后端返回的是{cases_count, cases, generation_log_id}结构
          if (response.data.data.cases && Array.isArray(response.data.data.cases)) {
            testCases.value = response.data.data.cases.map((item: any, index: number) => ({
              id: index + 1,
              title: item.title || `测试用例${index + 1}`,
              priority: convertPriorityToChinese(item.priority || 'medium'),
              steps: item.steps || `1. 执行测试步骤${index + 1}\n2. 验证功能是否正常工作`,
              expected_result: item.expected_result || `功能正常工作，符合预期要求`
            }));
            
            // 更新测试用例结果和分段
            testcaseResult.value = response.data.message || `成功生成${testCases.value.length}条测试用例`;
            parseTestcaseResult(testcaseResult.value);
            
            ElMessage.success('测试用例生成成功！');
          } else if (Array.isArray(response.data.data)) {
            // 兼容之前的数组格式
            testCases.value = response.data.data.map((item: any, index: number) => ({
              id: index + 1,
              title: item.title || `测试用例${index + 1}`,
              priority: convertPriorityToChinese(item.priority || 'medium'),
              steps: item.steps || `1. 执行测试步骤${index + 1}\n2. 验证功能是否正常工作`,
              expected_result: item.expected_result || `功能正常工作，符合预期要求`
            }));
            
            testcaseResult.value = response.data.message || `成功生成${testCases.value.length}条测试用例`;
            parseTestcaseResult(testcaseResult.value);
            
            ElMessage.success('测试用例生成成功！');
          } else {
            console.error('API返回数据结构异常:', response.data);
            ElMessage.error('测试用例生成失败：返回数据格式异常');
          }
        } else if (response.data && response.data.data && response.data.data.test_cases) {
          // 兼容旧格式
          testCases.value = response.data.data.test_cases.map((item: any, index: number) => ({
            id: index + 1,
            title: item.title || `测试用例${index + 1}`,
            priority: convertPriorityToChinese(item.priority || 'medium'),
            steps: item.steps || `1. 执行测试步骤${index + 1}\n2. 验证功能是否正常工作`,
            expected_result: item.expected_result || `功能正常工作，符合预期要求`
          }));
          
          testcaseResult.value = `成功生成${testCases.value.length}条测试用例`;
          parseTestcaseResult(testcaseResult.value);
          
          ElMessage.success('测试用例生成成功！');
        } else {
          console.error('API返回数据结构异常:', response.data);
          ElMessage.error('测试用例生成失败：返回数据格式异常');
        }
      } catch (error) {
        console.error('测试用例生成失败详情:', {
          message: (error as Error).message,
          response: (error as any).response ? {
            status: (error as any).response.status,
            statusText: (error as any).response.statusText,
            data: (error as any).response.data
          } : 'No response',
          config: (error as any).config
        });
        
        let errorMessage = '测试用例生成失败：' + (error as Error).message;
        if ((error as any).response && (error as any).response.data && (error as any).response.data.message) {
          errorMessage = '测试用例生成失败：' + (error as any).response.data.message;
        }
        
        ElMessage.error(errorMessage);
      } finally {
        testcaseLoading.value = false;
      }
    };
    
    // 解析测试用例结果为sections
    const parseTestcaseResult = (result: string) => {
      const sections = [];
      
      // 确保result不为空
      if (!result || result.trim() === '') {
        sections.push({
          title: '系统提示',
          content: '当前无法生成完整的测试用例报告。'
        });
        testcaseSections.value = sections;
        return;
      }
      
      // 解析测试用例结果
      sections.push({
        title: '测试用例概览',
        content: result
      });
      
      // 添加测试用例列表信息
      if (testCases.value && testCases.value.length > 0) {
        sections.push({
          title: '测试用例列表',
          content: `共生成${testCases.value.length}条测试用例，详细信息请查看下方表格。`
        });
      }
      
      testcaseSections.value = sections;
    };
    
    // 编辑测试用例
    const editTestCase = (row: any) => {
      ElMessage(`编辑测试用例：${row.title}`);
      // 这里应该是实际的测试用例编辑逻辑
    };
    
    // 删除测试用例
    const deleteTestCase = (id: number) => {
      ElMessage(`删除测试用例ID：${id}`);
      // 这里应该是实际的测试用例删除逻辑
    };
    
    // 格式化分析结果为HTML
    const formatAnalysisResult = (result: string) => {
      // 简单的Markdown转HTML处理
      return result
        .replace(/#{1,6}\s+([^\n]+)/g, (match: string, text: string) => {
          const matches = match.match(/#+/);
          const level = matches ? matches[0].length : 1;
          return `<h${level}>${text}</h${level}>`;
        })
        .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
        .replace(/\*(.*?)\*/g, '<em>$1</em>')
        .replace(/\n\n/g, '</p><p>')
        .replace(/^\s*-\s+(.*?)$/gm, '<li>$1</li>')
        .replace(/<\/li>\s*<li>/g, '</li><li>')
        .replace(/<p>\s*<li>/g, '<ul><li>')
        .replace(/<\/li>\s*<\/p>/g, '</li></ul>');
    };
    
    // 导出思维导图
    const exportMindmap = () => {
      if (!mindmapData.value) {
        ElMessage.warning('没有可导出的思维导图数据');
        return;
      }
      
      try {
        // 将思维导图数据转换为JSON字符串
        const jsonData = JSON.stringify(mindmapData.value, null, 2);
        
        // 创建Blob对象
        const blob = new Blob([jsonData], { type: 'application/json' });
        
        // 创建下载链接
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `mindmap-${new Date().getTime()}.json`;
        
        // 触发下载
        document.body.appendChild(link);
        link.click();
        
        // 清理
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        
        ElMessage.success('思维导图导出成功');
      } catch (error) {
        console.error('导出思维导图失败:', error);
        ElMessage.error('导出思维导图失败，请重试');
      }
    };
    
    // 完成流程
    const finishProcess = () => {
      ElMessage.success('需求分析流程已完成！');
    };
    
    // 获取文件类型显示名称
    const getFileType = (fileName: string) => {
      if (!fileName) return '未知';
      if (fileName.toLowerCase().endsWith('.docx')) return 'Word文档 (DOCX)';
      if (fileName.toLowerCase().endsWith('.doc')) return 'Word文档 (DOC)';
      if (fileName.toLowerCase().endsWith('.md')) return 'Markdown文档 (MD)';
      if (fileName.toLowerCase().endsWith('.txt')) return '文本文件 (TXT)';
      return '其他文件';
    };
    
    // 获取模型显示名称
    const getModelName = (modelValue: string) => {
      const modelMap: Record<string, string> = {
        'gpt-4': 'GPT-4',
        'gpt-3.5-turbo': 'GPT-3.5',
        'ernie-bot': '文心一言',
        'qwen': '通义千问',
        'deepseek': 'DeepSeek'
      };
      return modelMap[modelValue] || modelValue;
    };
    
    // 暴露给父组件的方法
    defineExpose({
      currentStep,
      selectedModel,
      apiKey,
      temperature,
      selectedTemplateId,
      customPrompt,
      uploadedFileName,
      fileContent,
      stats,
      analysisResult,
      analysisSections,
      mindmapData,
      testcaseResult,
      testcaseSections,
      testCases,
      handleFileUpload,
      generateAnalysis,
      goNext,
      goPrev,
      resetProcess,
      testAPIConnection,
      generateTestcases,
      editTestCase,
      deleteTestCase,
      exportMindmap,
      finishProcess,
      getFileType,
      getModelName
    });
</script setup>

<style scoped>
.ai-generation {
  padding: 20px;
  background-color: #f5f5f5;
  min-height: 100vh;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  background-color: #fff;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.step-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 40px;
  padding: 20px 0;
  background-color: #f8f9fa;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  transition: transform 0.3s ease;
}

.step:hover {
  transform: translateY(-2px);
}

.step-number {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #e0e0e0;
  color: #666;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 16px;
  margin-bottom: 8px;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  z-index: 1;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.step-text {
  font-size: 14px;
  color: #666;
  font-weight: 500;
  transition: all 0.3s ease;
  text-align: center;
  min-width: 100px;
}

.step.active .step-number {
  background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
  color: #fff;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
  transform: scale(1.1);
}

.step.active .step-number::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: rgba(64, 158, 255, 0.1);
  z-index: -1;
  animation: pulse 2s infinite;
}

.step.completed .step-number {
  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
  color: #fff;
}

.step.active .step-text {
  color: #409eff;
  font-weight: 600;
}

.step.completed .step-text {
  color: #67c23a;
  font-weight: 600;
}

.arrow {
  margin: 0 30px;
  color: #e0e0e0;
  font-size: 20px;
  transition: all 0.4s ease;
  position: relative;
}

.arrow.active {
  color: #409eff;
  transform: scale(1.2);
}

/* 连接线样式 */
.step::before {
  content: '';
  position: absolute;
  left: 100%;
  top: 20px;
  width: 60px;
  height: 3px;
  background-color: #e0e0e0;
  z-index: 0;
  margin-left: 15px;
  transition: all 0.4s ease;
}

.step:last-child::before {
  display: none;
}

.step.active::before,
.step.completed::before {
  background: linear-gradient(to right, #409eff, #66b1ff);
  height: 4px;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

/* 动画效果 */
@keyframes pulse {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.5);
    opacity: 0;
  }
}

.section-header {
  margin-bottom: 20px;
}

.section-header h2 {
  font-size: 24px;
  margin-bottom: 10px;
}

.section-header p {
  color: #666;
  margin: 0;
}

.model-config-section,
.template-section,
.custom-prompt-section,
.upload-section {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 8px;
}

.model-config-section h3,
.template-section h3,
.custom-prompt-section h3,
.upload-section h3 {
  margin-bottom: 15px;
  font-size: 18px;
}

.template-content {
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-preview {
  margin-top: 15px;
  padding: 10px;
  background-color: #f0f0f0;
  border-radius: 4px;
}

.file-name {
  font-weight: bold;
  margin-bottom: 5px;
}

.preview-text {
  font-size: 14px;
  color: #666;
  white-space: pre-wrap;
  word-break: break-word;
}

.error-message {
  color: #f56c6c;
  margin-bottom: 20px;
  padding: 10px;
  background-color: #fef0f0;
  border: 1px solid #fbc4c4;
  border-radius: 4px;
}

/* 总结卡片样式 */
.summary-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.summary-card {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.summary-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.summary-card-title {
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 2px solid #409eff;
}

.summary-card-content {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.summary-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.summary-label {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.summary-value {
  font-size: 14px;
  color: #333;
  font-weight: 600;
}

.summary-value.highlight {
  color: #409eff;
  font-size: 16px;
}

.analysis-result {
  background-color: #f9f9f9;
  padding: 20px;
  border-radius: 8px;
  line-height: 1.6;
}

.analysis-result h1 {
  font-size: 24px;
  margin-bottom: 20px;
}

.analysis-result h2 {
  font-size: 20px;
  margin-top: 25px;
  margin-bottom: 15px;
}

.analysis-result h3 {
  font-size: 18px;
  margin-top: 20px;
  margin-bottom: 10px;
}

.analysis-result p {
  margin-bottom: 10px;
}

.analysis-result ul {
  margin-bottom: 15px;
}

.analysis-result li {
  margin-bottom: 5px;
}

/* 模板详情对话框样式 */
.template-detail-dialog {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
}

.template-detail-dialog .el-dialog__header {
  background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
  color: white;
  padding: 20px 25px;
  border-bottom: none;
}

.template-detail-dialog .el-dialog__title {
  color: white;
  font-size: 18px;
  font-weight: 600;
}

.template-detail-dialog .el-dialog__body {
  padding: 0;
  overflow: hidden;
}

.template-detail-container {
  height: calc(100vh - 250px);
  display: flex;
  flex-direction: column;
}

/* 模板头部 */
.template-header {
  padding: 25px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
}

.template-main-title {
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.3;
}

.template-meta {
  display: flex;
  align-items: center;
  gap: 15px;
  font-size: 13px;
  color: #6c757d;
}

.template-divider {
  color: #dee2e6;
}

/* 模板内容卡片 */
.template-content-card {
  flex: 1;
  overflow-y: auto;
  padding: 30px;
  background-color: white;
}

.template-description {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  line-height: 1.7;
  color: #34495e;
}

/* 段落样式 */
.normal-paragraph {
  margin: 0 0 16px 0;
  text-indent: 2em;
  font-size: 15px;
}

.paragraph-spacing {
  height: 10px;
}

/* 标题样式 */
.section-title {
  margin: 30px 0 18px 0;
  color: #2c3e50;
  font-size: 18px;
  font-weight: 700;
  padding-left: 15px;
  border-left: 4px solid #409eff;
  background-color: #f8f9ff;
  padding: 12px 15px;
  border-radius: 0 6px 6px 0;
}

.subsection-title {
  margin: 24px 0 14px 0;
  color: #34495e;
  font-size: 16px;
  font-weight: 600;
  padding-bottom: 8px;
  border-bottom: 2px solid #e3f2fd;
}

/* 列表项样式 */
.list-item {
  margin: 0 0 12px 20px;
  padding-left: 15px;
  position: relative;
  font-size: 15px;
}

.list-item::before {
  content: "•";
  color: #409eff;
  position: absolute;
  left: 0;
  font-weight: bold;
}

/* 高亮文本样式 */
.highlight-text {
  background: linear-gradient(120deg, #fef9c3 0%, #fde68a 100%);
  color: #92400e;
  padding: 4px 8px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 14px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 提示框样式 */
.template-tips {
  background-color: #e3f2fd;
  border-top: 1px solid #bbdefb;
  padding: 20px 25px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.tip-icon {
  color: #1976d2;
  font-size: 20px;
  margin-top: 3px;
}

.tip-content {
  flex: 1;
  font-size: 14px;
  color: #1565c0;
  line-height: 1.6;
}

.tip-content p {
  margin: 0;
}

/* 对话框底部按钮 */
.dialog-footer .el-button {
  border-radius: 6px;
  padding: 8px 20px;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.dialog-footer .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

/* 自定义滚动条样式 */
.template-content-card::-webkit-scrollbar {
  width: 10px;
}

.template-content-card::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 5px;
}

.template-content-card::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 5px;
  transition: background 0.3s ease;
}

.template-content-card::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .template-detail-dialog {
    width: 95% !important;
    margin: 10px;
  }
  
  .template-header,
  .template-content-card,
  .template-tips {
    padding: 15px;
  }
  
  .template-main-title {
    font-size: 18px;
  }
}

/* 页面标题样式 */
.page-header {
  text-align: center;
  margin-bottom: 30px;
  padding: 20px 0;
}

.page-header .page-title {
  font-size: 28px;
  color: #333;
  margin-bottom: 10px;
  text-align: center;
}

.page-description {
  font-size: 14px;
  color: #606266;
  margin-top: 8px;
  text-align: center;
}

/* 隐藏的部分样式 */
.hidden-section {
  text-align: center;
  padding: 50px 20px;
}

.hidden-section h2 {
  color: #909399;
  margin-bottom: 15px;
}

.hidden-section p {
  color: #606266;
  margin-bottom: 30px;
}

.mindmap-container {
  background-color: #f9f9f9;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.mindmap-container-wrapper {
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  min-height: 500px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: box-shadow 0.3s ease;
}

.mindmap-container-wrapper:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

.start-generation {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
  background-color: #f5f7fa;
  border-radius: 8px;
  border: 2px dashed #dcdfe6;
  transition: all 0.3s ease;
}

.start-generation:hover {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.testcases-container {
  background-color: #f9f9f9;
  padding: 20px;
  border-radius: 8px;
}

.action-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 30px;
}
</style>